package bid

import (
	"context"
	"encoding/json"
	"fmt"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	opptyStatusRepo "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/business_opportunity/oppty_status"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/remote/bigdata_remote"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/remote/opensearch_remote"
	pb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/business_opportunity"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/business_opportunity/customer"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/business_opportunity/oppty_status"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/service/common/option"
	"git.myscrm.cn/golang/common/ykerrcode"
	"git.myscrm.cn/golang/stark/v4"
	aliyunoss "github.com/aliyun/aliyun-oss-go-sdk/oss"
	"io/ioutil"
	"strings"
)

type bidService struct {
	openSearchRepos    opensearch_remote.OpenSearchRepositoryIface
	opptyStatusRepos   opptyStatusRepo.GfyxOpptyStatusReposIface
	bigDataServiceRepo bigdata_remote.BigDataServiceRepositoryIface
	opptyStatusService oppty_status.OpptyStatusServiceIface
	optionService      option.OptionServiceIface
	customerService    customer.CustomerServiceIface
}

func NewBidService(
	openSearchRepos opensearch_remote.OpenSearchRepositoryIface,
	opptyStatusRepos opptyStatusRepo.GfyxOpptyStatusReposIface,
	bigDataServiceRepo bigdata_remote.BigDataServiceRepositoryIface,
	opptyStatusService oppty_status.OpptyStatusServiceIface,
	optionService option.OptionServiceIface,
	customerService customer.CustomerServiceIface,
) BidServiceIface {
	return &bidService{
		openSearchRepos:    openSearchRepos,
		opptyStatusRepos:   opptyStatusRepos,
		bigDataServiceRepo: bigDataServiceRepo,
		opptyStatusService: opptyStatusService,
		optionService:      optionService,
		customerService:    customerService,
	}
}

func (s *bidService) SearchBid(ctx context.Context, request *pb.SearchBidRequest) (*pb.SearchBidResponse, error) {
	//如果需要带股权过滤
	var organizingCodeArr []string
	if request.OrganizingCode != "" {
		organizingCodeArr, _ = s.bigDataServiceRepo.GetInvestCompanyCodes(ctx, request.OrganizingCode)
	}
	openSearchRequest := &opensearch_remote.SearchBidRequest{
		Page:             request.Page,
		PageSize:         request.PageSize,
		OrganizingCode:   strings.Join(organizingCodeArr, ","),
		Keyword:          request.Keyword,
		SearchType:       strings.Join(request.SearchType, ","),
		Id:               request.Id,
		SubId:            request.SubId,
		CompanyAreaCode:  strings.Join(request.CompanyAreaCode, ","),
		Type:             strings.Join(request.Type, ","),
		DataSourceCode:   strings.Join(request.DataSourceCode, ","),
		CompanyType:      strings.Join(request.CompanyType, ","),
		CompanyLabel:     strings.Join(request.CompanyLabel, ","),
		PublishDateStart: request.PublishDateStart,
		PublishDateEnd:   request.PublishDateEnd,
		EndDateStart:     request.EndDateStart,
		EndDateEnd:       request.EndDateEnd,
	}
	//区域
	request.AreaCode, _ = s.FilterAreaCode(ctx, request.AreaCode)
	openSearchRequest.AreaCode = strings.Join(request.AreaCode, ",")

	bidListResponse, err := s.openSearchRepos.SearchBid(ctx, openSearchRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "opensearch SearchBid,err:%s", err.Error())
	}
	result := &pb.SearchBidResponse{
		List: []*pb.BidData{},
	}
	if bidListResponse == nil {
		return result, nil
	}

	idList := make([]string, 0)
	companyNameArr := make([]string, 0)
	for _, value := range bidListResponse.List {
		idList = append(idList, value.Id)
		if value.FirstWinbidSupplierName != "" {
			companyNameArr = append(companyNameArr, value.FirstWinbidSupplierName)
		}
		if value.SecondWinbidSupplierName != "" {
			companyNameArr = append(companyNameArr, value.SecondWinbidSupplierName)
		}
		if value.ThirdWinbidSupplierName != "" {
			companyNameArr = append(companyNameArr, value.ThirdWinbidSupplierName)
		}
		companyNameArr = append(companyNameArr, value.DeveloperName)
	}
	//数据预处理
	companyTarget := s.customerService.GetCompanyTarget(ctx, companyNameArr) //公司指标
	for _, item := range bidListResponse.List {
		data := &pb.BidData{
			Id:                       item.Id,
			Title:                    item.Title,
			DeveloperName:            item.DeveloperName,
			OrganizingCode:           item.OrganizingCode,
			TopCompanyName:           item.TopCompanyName,
			TopCompanyOrganizingCode: item.TopCompanyOrganizingCode,
			CompanyProvince:          item.CompanyProvince,
			CompanyProvinceCode:      item.CompanyProvinceCode,
			CompanyCity:              item.CompanyCity,
			CompanyCityCode:          item.CompanyCityCode,
			PublishDate:              item.PublishDate,
			EndDate:                  item.EndDate,
			DataSourceCode:           item.DataSourceCode,
			DataSource:               constants.GetBidDataSourceName(item.DataSourceCode), //公告类型映射
			Title_HL:                 item.TitleHL,
			DeveloperName_HL:         item.DeveloperNameHL,
			XScore:                   item.XScore,
			CompanyType:              item.CompanyType,
			Type:                     item.Type,
		}
		if len(data.PublishDate) >= 10 {
			data.PublishDate = data.PublishDate[:10]
		}
		if len(data.EndDate) >= 10 {
			data.EndDate = data.EndDate[:10]
		}
		//联系人数量 PurchaseContactCnt、CoopSupplierContactCnt、FirstWinbidSupplierContactCnt、SecondWinbidSupplierContactCnt、ThirdWinbidSupplierContactCnt
		for _, v := range companyTarget {
			if item.DeveloperName == v.DeveloperName {
				data.PurchaseContactCnt = v.PurchaseContactCnt
				data.CoopSupplierContactCnt = v.CoopSupplierContactCnt
			}
			if item.FirstWinbidSupplierName == v.DeveloperName {
				data.FirstWinbidSupplierContactCnt = v.SupplierContactCnt
			}
			if item.SecondWinbidSupplierName == v.DeveloperName {
				data.SecondWinbidSupplierContactCnt = v.SupplierContactCnt
			}
			if item.ThirdWinbidSupplierName == v.DeveloperName {
				data.ThirdWinbidSupplierContactCnt = v.SupplierContactCnt
			}
		}
		//企业标签
		companyLabelArr := make([]string, 0)
		for _, v := range item.CompanyLabelArr {
			companyLabelArr = append(companyLabelArr, v.Label)
		}
		data.CompanyLabelArr = strings.Join(companyLabelArr, ",")

		//省份城市
		for _, v := range item.ProjectProvince {
			data.ProjectProvince = append(data.ProjectProvince, &pb.ProjectProvinceInfo{
				Province:     v.Province,
				ProvinceCode: v.ProvinceCode,
				City:         v.City,
				CityCode:     v.CityCode,
			})
		}
		//中标单位格式处理+去重
		supplierList := []*pb.SupplierList{
			{
				SupplierName:           item.FirstWinbidSupplierName,
				SupplierName_HL:        item.FirstWinbidSupplierNameHL,
				SupplierOrganizingCode: item.FirstWinbidSupplierOrganizingCode,
			},
			{
				SupplierName:           item.FirstWinbidSupplierName,
				SupplierName_HL:        item.FirstWinbidSupplierNameHL,
				SupplierOrganizingCode: item.FirstWinbidSupplierOrganizingCode,
			},
			{
				SupplierName:           item.ThirdWinbidSupplierName,
				SupplierName_HL:        item.ThirdWinbidSupplierNameHL,
				SupplierOrganizingCode: item.ThirdWinbidSupplierOrganizingCode,
			},
		}
		supplierNameSet := make(map[string]bool)
		for _, v := range supplierList {
			if v.SupplierName == "" {
				continue
			}
			if _, ok := supplierNameSet[v.SupplierName]; !ok {
				//如果不存在
				data.SupplierList = append(data.SupplierList, v)
				supplierNameSet[v.SupplierName] = true
			}
		}
		result.List = append(result.List, data)
	}
	//处理联系人总数
	for _, item2 := range result.List {
		if item2.Type == "招标" { //招标联系人： 甲方+合作单位
			item2.ContactCnt = item2.PurchaseContactCnt + item2.CoopSupplierContactCnt
		} else { //中标联系人：甲方+中标（每家中标单位数量不超过2）
			var firstWinbidSupplierContactCnt, secondWinbidSupplierContactCnt, thirdWinbidSupplierContactCnt int32
			if item2.FirstWinbidSupplierContactCnt > 2 {
				firstWinbidSupplierContactCnt = 2
			} else {
				firstWinbidSupplierContactCnt = item2.FirstWinbidSupplierContactCnt
			}
			if item2.SecondWinbidSupplierContactCnt > 2 {
				secondWinbidSupplierContactCnt = 2
			} else {
				secondWinbidSupplierContactCnt = item2.SecondWinbidSupplierContactCnt
			}
			if item2.ThirdWinbidSupplierContactCnt > 2 {
				thirdWinbidSupplierContactCnt = 2
			} else {
				thirdWinbidSupplierContactCnt = item2.ThirdWinbidSupplierContactCnt
			}
			item2.ContactCnt = item2.PurchaseContactCnt + firstWinbidSupplierContactCnt + secondWinbidSupplierContactCnt + thirdWinbidSupplierContactCnt
		}
	}

	//商机状态
	getOpptyStatusBatchRequest := &pb.GetOpptyStatusBatchRequest{
		DataSource:   constants.OpptySourceBidMerge,
		DataSourceId: idList,
	}
	opptyStatus, err := s.opptyStatusService.GetOpptyStatusBatch(ctx, getOpptyStatusBatchRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "GetOpptyStatusBatch接口异常:%s,错误信息:%s", err)
	}
	for _, item := range result.List {
		for _, opptyValue := range opptyStatus {
			if item.Id != "" && item.Id == opptyValue.DataSourceId {
				item.OpptyStatus = opptyValue.StatusName
			}
		}
	}
	result.Total = bidListResponse.Total
	return result, nil
}

func (s *bidService) FilterAreaCode(ctx context.Context, areaCodeList []string) ([]string, error) {
	newAreaCodeList := make([]string, 0)
	defaultAreaCode, err := s.optionService.GetRadarAreaOption(ctx)
	if err != nil {
		stark.Logger.Infof(ctx, "GetRadarAreaOption err:%s", err.Error())
		return newAreaCodeList, err
	}
	if defaultAreaCode != nil {
		if len(areaCodeList) == 0 {
			for _, v := range defaultAreaCode.Options {
				newAreaCodeList = append(newAreaCodeList, v.AreaCode)
			}
			// todo 因为业务需求调整，暂时不需要过滤，通过权限和权益接口进行控制
			//if len(newAreaCodeList) == 0 { //如果权益没有一个省份：传递-1，即列表不返回任何数据
			//	newAreaCodeList = append(newAreaCodeList, "-1")
			//}
		} else {
			for _, pv := range areaCodeList {
				for _, qv := range defaultAreaCode.Options {
					if pv == qv.AreaCode {
						newAreaCodeList = append(newAreaCodeList, qv.AreaCode)
					}
				}
			}
		}
	}
	return newAreaCodeList, nil
}

func (s *bidService) FuzzySearchBid(ctx context.Context, request *pb.FuzzySearchBidRequest) (*pb.FuzzySearchBidResponse, error) {
	openSearchRequest := &opensearch_remote.FuzzySearchBidRequest{
		Keyword:    request.Keyword,
		SearchType: request.SearchType,
	}
	fuzzyBidResponse, err := s.openSearchRepos.FuzzySearchBid(ctx, openSearchRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "opensearch FuzzySearchBid,err:%s", err.Error())
	}
	result := &pb.FuzzySearchBidResponse{}
	if fuzzyBidResponse == nil {
		return result, nil
	}

	for _, item := range fuzzyBidResponse {
		data := &pb.FuzzySearchBidItem{
			TitleHL: item.TitleHL,
			Title:   item.Title,
		}
		result.List = append(result.List, data)
	}
	return result, nil
}

func (s *bidService) BidDetail(ctx context.Context, request *pb.BidDetailRequest) (*pb.BidDetailResponse, error) {
	//招标信息
	bigDataRequest := &bigdata_remote.BidListRequest{
		PageNum:  1,
		PageSize: 1,
		Id:       request.Id,
	}
	getBidListResponse, err := s.bigDataServiceRepo.BidList(ctx, bigDataRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "bigdata BidList,err:%s", err.Error())
	}
	resp := &pb.BidDetailResponse{}
	if getBidListResponse != nil && len(getBidListResponse.List) > 0 {
		resp.Id = getBidListResponse.List[0].ID
		resp.AgentOwer = getBidListResponse.List[0].AgentOwer
		resp.AgentOwerMobile = getBidListResponse.List[0].AgentOwerMobile
		resp.AgentOrganization = getBidListResponse.List[0].AgentOrganization
		resp.BiddingServiceCategory = getBidListResponse.List[0].BiddingServiceCategory
		resp.ContentId = getBidListResponse.List[0].ContentID
		resp.CreatedAt = getBidListResponse.List[0].CreatedAt
		resp.DataSourceCode = getBidListResponse.List[0].DataSourceCode
		resp.DeveloperName = getBidListResponse.List[0].DeveloperName
		resp.EndTime = getBidListResponse.List[0].EndTime
		resp.IsMatchMaster = getBidListResponse.List[0].IsMatchMaster
		resp.OrganizingCode = getBidListResponse.List[0].OrganizingCode
		resp.Ower = getBidListResponse.List[0].Ower
		resp.OwerMobile = getBidListResponse.List[0].OwerMobile
		resp.PublishTime = getBidListResponse.List[0].PublishTime
		resp.Title = getBidListResponse.List[0].Title
		resp.TopOrganizingCode = getBidListResponse.List[0].TopOrganizingCode
		resp.TopDeveloperName = getBidListResponse.List[0].TopDeveloperName
		resp.TopCompanyType = getBidListResponse.List[0].TopCompanyType
		resp.TopParentCompanyType = getBidListResponse.List[0].TopParentCompanyType
		resp.Url = getBidListResponse.List[0].URL
		resp.Uid = getBidListResponse.List[0].UID
		resp.WebsiteName = getBidListResponse.List[0].WebsiteName
		resp.Detail = getBidListResponse.List[0].Detail
		//公告类型映射
		switch resp.DataSourceCode {
		case constants.DataSourceCodeTradingCenter:
			resp.DataSource = constants.DataSourceCodeTradingCenterName
			break
		case constants.DataSourceCodeWebsiteBid:
			resp.DataSource = constants.DataSourceCodeWebsiteBidName
			break
		case constants.DataSourceCodeYcgRecruit:
			resp.DataSource = constants.DataSourceCodeYcgRecruitName
			break
		case constants.DataSourceCodeYcgBid:
			resp.DataSource = constants.DataSourceCodeYcgBidName
			break
		default:
			resp.DataSource = ""
		}
		//采购金额
		purchaseAmount, err := utils.Decimal(getBidListResponse.List[0].PurchaseAmount, "2")
		if err != nil {
			stark.Logger.Errorf(ctx, "string to float,err:%s", err.Error())
		}
		purchaseAmount, err = utils.DecimalFloat(purchaseAmount / 10000)
		resp.PurchaseAmount = purchaseAmount
		//省份城市
		if getBidListResponse.List[0].ProvinceAndCity != "" {
			err = json.Unmarshal([]byte(getBidListResponse.List[0].ProvinceAndCity), &resp.ProjectProvince)
			if err != nil {
				stark.Logger.Errorf(ctx, "json Unmarshal ,err:%s", err.Error())
			}
		}
		//平台招标招募
		if resp.DataSourceCode == constants.DataSourceCodeYcgBid || resp.DataSourceCode == constants.DataSourceCodeYcgRecruit {
			resp.OwerMobile = utils.GetMobileEncrypt(resp.OwerMobile)
			resp.OwerMobileVisible = false
		} else {
			resp.OwerMobileVisible = true
		}
		//ContentHtml字段
		if resp.DataSourceCode == constants.DataSourceCodeTradingCenter || resp.DataSourceCode == constants.DataSourceCodeWebsiteBidName {
			filePath := s.GetBidContentPath(resp.PublishTime, resp.WebsiteName, resp.ContentId)
			contentHtml, err := s.GetBidOssFile(filePath)
			if err != nil {
				stark.Logger.Errorf(ctx, "get oss bid_content,err:%s", err.Error())
			}
			resp.ContentHtml = contentHtml
		}
		//oppty_status字段
		opptyStatusRequest := &pb.GetOpptyStatusRequest{
			DataSource:   constants.OpptySourcePurchase,
			DataSourceId: request.Id,
			DetailPage:   true,
		}
		opptyStatus, err := s.opptyStatusService.GetOpptyStatus(ctx, opptyStatusRequest)
		if err != nil {
			stark.Logger.Errorf(ctx, "GetOpptyStatus,err:%s", err.Error())
		}
		resp.OpptyStatus = opptyStatus.StatusName
		//detail字段
		if resp.Detail == "" && (resp.DataSourceCode == constants.DataSourceCodeTradingCenter || resp.DataSourceCode == constants.DataSourceCodeWebsiteBid) {
			tradeCenterRequest := &bigdata_remote.TradingCenterBidRequest{
				PageNum:  1,
				PageSize: 1,
				Uid:      resp.Uid,
			}
			tradeCenterBidResponse, err := s.bigDataServiceRepo.TradingCenterBid(ctx, tradeCenterRequest)
			if err != nil {
				stark.Logger.Errorf(ctx, "bigdata TradingCenterBid,err:%s", err.Error())
			}
			if tradeCenterBidResponse != nil && tradeCenterBidResponse.Total > 0 {
				resp.Detail = s.getBidContentJoin(ctx, tradeCenterBidResponse.List[0])
			}
		}
		//关联公司:招标单位、招标单位
		resp.RelatedCompany = make([]*pb.BidRelatedCompany, 0)
		if getBidListResponse.List[0].DeveloperName != "" {
			labels := make([]string, 0)
			if getBidListResponse.List[0].CompanyTypeLabel != "" {
				labels = append(labels, getBidListResponse.List[0].CompanyTypeLabel)
			}
			resp.RelatedCompany = append(resp.RelatedCompany, &pb.BidRelatedCompany{
				CompanyName:    getBidListResponse.List[0].DeveloperName,
				OrganizingCode: getBidListResponse.List[0].OrganizingCode,
				Role:           constants.RelatedCompanyTypeDeveloperCompany,
				Labels:         labels,
			})
		}
		if getBidListResponse.List[0].AgentOrganization != "" {
			resp.RelatedCompany = append(resp.RelatedCompany, &pb.BidRelatedCompany{
				CompanyName: getBidListResponse.List[0].AgentOrganization,
				Role:        constants.RelatedCompanyTypeAgentUnit,
				Labels:      make([]string, 0),
			})
		}
		if getBidListResponse.List[0].Ower != "" || getBidListResponse.List[0].OwerMobile != "" {
			resp.RelatedOwner = append(resp.RelatedOwner, &pb.BidRelatedOwner{
				Name:   getBidListResponse.List[0].Ower,
				Mobile: utils.GetMobileEncrypt(getBidListResponse.List[0].OwerMobile),
				Role:   constants.RelatedOwnerTypeBid,
			})
		}
		if getBidListResponse.List[0].AgentOwer != "" || getBidListResponse.List[0].AgentOwerMobile != "" {
			resp.RelatedOwner = append(resp.RelatedOwner, &pb.BidRelatedOwner{
				Name:   getBidListResponse.List[0].AgentOwer,
				Mobile: utils.GetMobileEncrypt(getBidListResponse.List[0].AgentOwerMobile),
				Role:   constants.RelatedOwnerTypeAgent,
			})
		}

	} else {
		return nil, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "招标详情不存在,id:"+request.Id)
	}
	return resp, nil
}

func (s *bidService) BidDetailMobile(ctx context.Context, request *pb.BidDetailMobileRequest) (*pb.BidDetailMobileResponse, error) {
	//招标信息
	bigDataRequest := &bigdata_remote.BidListRequest{
		PageNum:  1,
		PageSize: 1,
		Id:       request.Id,
	}
	getBidListResponse, err := s.bigDataServiceRepo.BidList(ctx, bigDataRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "bigdata BidList,err:%s", err.Error())
	}
	resp := &pb.BidDetailMobileResponse{}
	if getBidListResponse != nil && getBidListResponse.Total > 0 {
		resp.Id = getBidListResponse.List[0].ID
		resp.AgentOwerMobile = getBidListResponse.List[0].AgentOwerMobile
		resp.OwerMobile = getBidListResponse.List[0].OwerMobile
	}
	return resp, nil
}

func (s *bidService) getBidContentJoin(ctx context.Context, request *bigdata_remote.TradingCenterBidItem) string {
	html := ""
	html += "<p>项目编号：" + request.ProjectNumber + "</p>"
	html += "<p>项目名称：" + request.ProjectName + "</p>"
	html += "<p>项目所在地：" + request.Address + "</p>"
	html += "<p>招标单位：" + request.DeveloperName + "</p>"
	html += "<p>招标单位地址：" + request.OwerAddress + "</p>"
	html += "<p>招标单位联系电话：" + utils.GetMobileEncrypt(request.OwerPhone) + "</p>"
	html += "<p>招标单位联系人：" + utils.GetContactNameEncrypt(request.OwerContact) + "</p>"
	html += "<p>代理机构：" + request.AgentUnit + "</p>"
	html += "<p>代理机构联系电话：" + utils.GetMobileEncrypt(request.AgentPhone) + "</p>"
	html += "<p>代理机构联系人：" + utils.GetContactNameEncrypt(request.AgentContact) + "</p>"
	html += "<p>代理机构地址：" + request.AgentAddress + "</p>"
	html += "<p>建设规模：" + request.BuildScale + "</p>"
	html += "<p>业务类型：" + request.BusinessType + "</p>"
	html += "<p>工期：" + request.ConstructionTimeLimit + "</p>"
	html += "<p>资格要求：" + request.Qualification + "</p>"
	html += "<p>业务类型：" + request.BusinessType + "</p>"
	html += "<p>资金来源：" + request.FundSource + "</p>"
	html += "<p>项目预算（投标最高限价）：" + request.Budget + "</p>"
	return html
}

func (s *bidService) WinBidDetail(ctx context.Context, request *pb.WinBidDetailRequest) (*pb.WinBidDetailResponse, error) {
	//中标信息
	bigDataRequest := &bigdata_remote.WinBidListRequest{
		PageNum:  1,
		PageSize: 1,
		Id:       request.Id,
	}
	winBidListResponse, err := s.bigDataServiceRepo.WinBidList(ctx, bigDataRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "bigdata WinBidList,err:%s", err.Error())
	}
	resp := &pb.WinBidDetailResponse{}
	if winBidListResponse != nil && len(winBidListResponse.List) > 0 {
		resp.Id = winBidListResponse.List[0].ID
		resp.AgentAddress = winBidListResponse.List[0].AgentAddress
		resp.AgentContact = winBidListResponse.List[0].AgentContact
		resp.AgentPhone = winBidListResponse.List[0].AgentPhone
		resp.AgentUnit = winBidListResponse.List[0].AgentUnit
		resp.BidMaxLimitPrice = winBidListResponse.List[0].BidMaxLimitPrice
		resp.Category = winBidListResponse.List[0].Category
		resp.City = winBidListResponse.List[0].City
		resp.CityCode = winBidListResponse.List[0].CityCode
		resp.ContentId = winBidListResponse.List[0].ContentId
		resp.DeveloperTop_100Label = winBidListResponse.List[0].DeveloperTop100Label
		resp.FirstWinbidPrice, err = utils.DecimalFloat(winBidListResponse.List[0].FirstWinbidPrice / 10000)
		resp.FirstWinbidSupplierAddress = winBidListResponse.List[0].FirstWinbidSupplierAddress
		resp.FirstWinbidSupplierName = winBidListResponse.List[0].FirstWinbidSupplierName
		resp.FirstWinbidSupplierOrganizingCode = winBidListResponse.List[0].FirstWinbidSupplierOrganizingCode
		resp.LinkUrl = winBidListResponse.List[0].LinkUrl
		resp.NewAreaExpandLabel = winBidListResponse.List[0].NewAreaExpandLabel
		resp.NewDecorateExpandLabel = winBidListResponse.List[0].NewDecorateExpandLabel
		resp.NewLandUsageExpandLabel = winBidListResponse.List[0].NewLandUsageExpandLabel
		resp.OpenTime = strings.Split(winBidListResponse.List[0].OpenTime, " ")[0]
		resp.OrganizingCode = winBidListResponse.List[0].OrganizingCode
		resp.OwerAddress = winBidListResponse.List[0].OwerAddress
		resp.OwerContact = winBidListResponse.List[0].OwerContact
		resp.OwerPhone = winBidListResponse.List[0].OwerPhone
		resp.OwerUnit = winBidListResponse.List[0].OwerUnit
		resp.PriceGtAvgLabel = winBidListResponse.List[0].PriceGtAvgLabel
		resp.ProjectAddress = winBidListResponse.List[0].ProjectAddress
		resp.ProjectName = winBidListResponse.List[0].ProjectName
		resp.ProjectNumber = winBidListResponse.List[0].ProjectNumber
		resp.ProjectOwer = winBidListResponse.List[0].ProjectOwer
		resp.Province = winBidListResponse.List[0].Province
		resp.ProvinceCode = winBidListResponse.List[0].ProvinceCode
		resp.PublishTime = strings.Split(winBidListResponse.List[0].PublishTime, " ")[0]
		resp.SecondWinbidPrice, err = utils.DecimalFloat(winBidListResponse.List[0].SecondWinbidPrice / 10000)
		resp.SecondWinbidSupplierAddress = winBidListResponse.List[0].SecondWinbidSupplierAddress
		resp.SecondWinbidSupplierName = winBidListResponse.List[0].SecondWinbidSupplierName
		resp.SecondWinbidSupplierOrganizingCode = winBidListResponse.List[0].SecondWinbidSupplierOrganizingCode
		resp.SecondWinbidSupplierPhone = winBidListResponse.List[0].SecondWinbidSupplierPhone
		resp.Source = winBidListResponse.List[0].Source
		resp.SourceSub = winBidListResponse.List[0].SourceSub
		resp.ThirdWinbidPrice, err = utils.DecimalFloat(winBidListResponse.List[0].ThirdWinbidPrice / 10000)
		resp.ThirdWinbidSupplierAddress = winBidListResponse.List[0].ThirdWinbidSupplierAddress
		resp.ThirdWinbidSupplierName = winBidListResponse.List[0].ThirdWinbidSupplierName
		resp.ThirdWinbidSupplierOrganizingCode = winBidListResponse.List[0].ThirdWinbidSupplierOrganizingCode
		resp.ThirdWinbidSupplierPhone = winBidListResponse.List[0].ThirdWinbidSupplierPhone
		resp.Title = winBidListResponse.List[0].Title
		resp.Type = winBidListResponse.List[0].Type
		resp.WebsiteName = winBidListResponse.List[0].WebsiteName

		//最大限额
		bidMaxLimitPrice, err := utils.DecimalFloat(winBidListResponse.List[0].BidMaxLimitPrice / 10000)
		if err != nil {
			stark.Logger.Errorf(ctx, "string to float,err:%s", err.Error())
		}
		resp.BidMaxLimitPrice = bidMaxLimitPrice
		//html_content字段
		filePath := s.GetWinBidContentPath(resp.PublishTime, resp.WebsiteName, resp.ContentId)
		contentHtml, err := s.GetBidOssFile(filePath)
		resp.ContentHtml = contentHtml
		//关联公司:招标单位、招标单位
		resp.RelatedCompany = make([]*pb.BidRelatedCompany, 0)
		if winBidListResponse.List[0].OwerUnit != "" {
			labels := make([]string, 0)
			if winBidListResponse.List[0].BidCompanyTypeLabel != "" {
				labels = append(labels, winBidListResponse.List[0].BidCompanyTypeLabel)
			}
			resp.RelatedCompany = append(resp.RelatedCompany, &pb.BidRelatedCompany{
				CompanyName:    winBidListResponse.List[0].OwerUnit,
				OrganizingCode: winBidListResponse.List[0].OrganizingCode,
				Role:           constants.RelatedCompanyTypeDeveloperCompany,
				Labels:         labels,
			})
		}
		if winBidListResponse.List[0].FirstWinbidSupplierName != "" {
			labels := make([]string, 0)
			if winBidListResponse.List[0].FirstWinbidCompanyTypeLabel != "" {
				labels = append(labels, winBidListResponse.List[0].FirstWinbidCompanyTypeLabel)
			}
			resp.RelatedCompany = append(resp.RelatedCompany, &pb.BidRelatedCompany{
				CompanyName:    winBidListResponse.List[0].FirstWinbidSupplierName,
				OrganizingCode: winBidListResponse.List[0].FirstWinbidSupplierOrganizingCode,
				Role:           constants.RelatedCompanyTypeSupplierCompany,
				Labels:         labels,
			})
		}
		if winBidListResponse.List[0].SecondWinbidSupplierName != "" {
			labels := make([]string, 0)
			if winBidListResponse.List[0].SecondWinbidCompanyTypeLabel != "" {
				labels = append(labels, winBidListResponse.List[0].SecondWinbidCompanyTypeLabel)
			}
			resp.RelatedCompany = append(resp.RelatedCompany, &pb.BidRelatedCompany{
				CompanyName:    winBidListResponse.List[0].SecondWinbidSupplierName,
				OrganizingCode: winBidListResponse.List[0].SecondWinbidSupplierOrganizingCode,
				Role:           constants.RelatedCompanyTypeSupplierCompany,
				Labels:         labels,
			})
		}
		if winBidListResponse.List[0].ThirdWinbidSupplierName != "" {
			labels := make([]string, 0)
			if winBidListResponse.List[0].ThirdWinbidCompanyTypeLabel != "" {
				labels = append(labels, winBidListResponse.List[0].ThirdWinbidCompanyTypeLabel)
			}
			resp.RelatedCompany = append(resp.RelatedCompany, &pb.BidRelatedCompany{
				CompanyName:    winBidListResponse.List[0].ThirdWinbidSupplierName,
				OrganizingCode: winBidListResponse.List[0].ThirdWinbidSupplierOrganizingCode,
				Role:           constants.RelatedCompanyTypeSupplierCompany,
				Labels:         labels,
			})
		}
		if winBidListResponse.List[0].AgentUnit != "" {
			resp.RelatedCompany = append(resp.RelatedCompany, &pb.BidRelatedCompany{
				CompanyName: winBidListResponse.List[0].AgentUnit,
				Role:        constants.RelatedCompanyTypeAgentUnit,
				Labels:      make([]string, 0),
			})
		}
		//oppty_status字段
		opptyStatusRequest := &pb.GetOpptyStatusRequest{
			DataSource:   constants.OpptySourceWinBid,
			DataSourceId: request.Id,
			DetailPage:   true,
		}
		opptyStatus, err := s.opptyStatusService.GetOpptyStatus(ctx, opptyStatusRequest)
		if err != nil {
			stark.Logger.Errorf(ctx, "GetOpptyStatus,err:%s", err.Error())
		}
		resp.OpptyStatus = opptyStatus.StatusName
	} else {
		return nil, ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "中标详情不存在,id:"+request.Id)
	}
	return resp, nil
}

func (s *bidService) GetBidContentPath(publishTime string, websiteName string, id string) string {
	if publishTime == "" {
		return ""
	}
	if len(publishTime) >= 10 {
		publishTime = publishTime[0:10]
	}
	if websiteName == "" {
		websiteName = "other"
	}
	return "pub_bid/" + publishTime + "/" + websiteName + "/" + id + ".txt"
}

func (s *bidService) GetWinBidContentPath(publishTime string, websiteName string, id string) string {
	if publishTime == "" {
		return ""
	}
	if len(publishTime) >= 10 {
		publishTime = publishTime[0:10]
	}
	if websiteName == "" {
		websiteName = "other"
	}
	return "win_bid/" + publishTime + "/" + websiteName + "/" + id + ".txt"
}

func (s *bidService) GetBidOssFile(ossFilePath string) (string, error) {
	endpoint := "https://oss-cn-hangzhou.aliyuncs.com"
	accessKeyId := "LTAI5tAkWjrrenAugNcuuWTA"
	accessKeySecret := "4k7QKFjVqps3etGorMUl8LxczA0K0P"
	client, err := aliyunoss.New(endpoint, accessKeyId, accessKeySecret)
	bucketName := "gfyx-saas-bid-content"
	if err != nil {
		return "", err
	}
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		return "", err
	}

	object, err := bucket.GetObject(ossFilePath)
	if err != nil {
		return "", err
	}

	content, err := ioutil.ReadAll(object)
	if err != nil {
		return "", err
	}
	return string(content), nil
}

// GetExportBiddingTotal  导出客户详情-采购需求列表获取总记录数
func (s *bidService) GetExportBiddingTotal(ctx context.Context, condition interface{}) (total int64, err error) {
	var request *pb.SearchBidRequest
	switch condition.(type) {
	case *pb.SearchBidRequest:
		request = condition.(*pb.SearchBidRequest)
	case string:
		request = &pb.SearchBidRequest{}
		if condition.(string) != "" {
			err = json.Unmarshal([]byte(condition.(string)), request)
			if err != nil {
				stark.Logger.Errorf(ctx, "找招标导出记录条数错误,condition:%+v, err:%s", condition, err)
				return
			}
		}
	}
	// 获取总条目，只需要取一条数据就好了
	var organizingCodeArr []string
	if request.OrganizingCode != "" {
		organizingCodeArr, _ = s.bigDataServiceRepo.GetInvestCompanyCodes(ctx, request.OrganizingCode)
	}
	openSearchRequest := &opensearch_remote.SearchBidRequest{
		Page:             1,
		PageSize:         1,
		OrganizingCode:   strings.Join(organizingCodeArr, ","),
		Keyword:          request.Keyword,
		SearchType:       strings.Join(request.SearchType, ","),
		Id:               request.Id,
		SubId:            request.SubId,
		CompanyAreaCode:  strings.Join(request.CompanyAreaCode, ","),
		Type:             strings.Join(request.Type, ","),
		DataSourceCode:   strings.Join(request.DataSourceCode, ","),
		CompanyType:      strings.Join(request.CompanyType, ","),
		CompanyLabel:     strings.Join(request.CompanyLabel, ","),
		PublishDateStart: request.PublishDateStart,
		PublishDateEnd:   request.PublishDateEnd,
		EndDateStart:     request.EndDateStart,
		EndDateEnd:       request.EndDateEnd,
	}
	//区域
	request.AreaCode, _ = s.FilterAreaCode(ctx, request.AreaCode)
	openSearchRequest.AreaCode = strings.Join(request.AreaCode, ",")

	searchData, err := s.openSearchRepos.SearchBid(ctx, openSearchRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "opensearch SearchBid,err:%s", err.Error())
	}
	if searchData == nil {
		return
	}

	total = int64(searchData.Total)
	return
}

// QueryExportBiddingBatchData 导出客户详情-采购需求列表，分批获取数据
func (s *bidService) QueryExportBiddingBatchData(ctx context.Context, condition interface{}, batchNum, batchSize int32) (rowTitle []string, rowData [][]string, err error) {
	rowTitle = strings.Split(constants.OrderTypeBidExportFields, "，")
	var request *pb.SearchBidRequest
	switch condition.(type) {
	case *pb.SearchBidRequest:
		request = condition.(*pb.SearchBidRequest)
	case string:
		request = &pb.SearchBidRequest{}
		if condition.(string) != "" {
			err = json.Unmarshal([]byte(condition.(string)), request)
			if err != nil {
				stark.Logger.Errorf(ctx, "找招标导出记录条数错误,condition:%+v, err:%s", condition, err)
				return
			}
		}
	}
	// 获取总条目，只需要取一条数据就好了
	//如果需要带股权过滤
	var organizingCodeArr []string
	if request.OrganizingCode != "" {
		organizingCodeArr, _ = s.bigDataServiceRepo.GetInvestCompanyCodes(ctx, request.OrganizingCode)
	}
	openSearchRequest := &opensearch_remote.SearchBidRequest{
		Page:             batchNum,
		PageSize:         batchSize,
		OrganizingCode:   strings.Join(organizingCodeArr, ","),
		Keyword:          request.Keyword,
		SearchType:       strings.Join(request.SearchType, ","),
		Id:               request.Id,
		SubId:            request.SubId,
		CompanyAreaCode:  strings.Join(request.CompanyAreaCode, ","),
		Type:             strings.Join(request.Type, ","),
		DataSourceCode:   strings.Join(request.DataSourceCode, ","),
		CompanyType:      strings.Join(request.CompanyType, ","),
		CompanyLabel:     strings.Join(request.CompanyLabel, ","),
		PublishDateStart: request.PublishDateStart,
		PublishDateEnd:   request.PublishDateEnd,
		EndDateStart:     request.EndDateStart,
		EndDateEnd:       request.EndDateEnd,
	}
	//区域
	request.AreaCode, _ = s.FilterAreaCode(ctx, request.AreaCode)
	openSearchRequest.AreaCode = strings.Join(request.AreaCode, ",")

	searchData, err := s.openSearchRepos.SearchBid(ctx, openSearchRequest)
	if err != nil {
		stark.Logger.Errorf(ctx, "opensearch SearchBid,err:%s", err.Error())
	}
	if searchData == nil {
		return
	}

	for _, item := range searchData.List {
		publishDate := item.PublishDate
		endDate := item.EndDate
		if len(publishDate) >= 10 {
			publishDate = publishDate[:10]
		}
		if len(endDate) >= 10 {
			endDate = endDate[:10]
		}
		var supplierNameArr []string
		if item.FirstWinbidSupplierName != "" {
			supplierNameArr = append(supplierNameArr, item.FirstWinbidSupplierName)
		}
		if item.SecondWinbidSupplierName != "" &&
			item.SecondWinbidSupplierName != item.FirstWinbidSupplierName {
			supplierNameArr = append(supplierNameArr, item.SecondWinbidSupplierName)
		}
		if item.ThirdWinbidSupplierName != "" &&
			item.ThirdWinbidSupplierName != item.FirstWinbidSupplierName &&
			item.ThirdWinbidSupplierName != item.SecondWinbidSupplierName {
			supplierNameArr = append(supplierNameArr, item.ThirdWinbidSupplierName)
		}
		//省份城市
		var addressArr []string
		for _, v := range item.ProjectProvince {
			address := v.Province + v.City
			if v.Province == v.City {
				address = v.Province
			}
			addressArr = append(addressArr, address)
		}
		var label []string
		for _, v := range item.CompanyLabelArr {
			label = append(label, v.Label)
		}

		ownerContacts := ""
		if item.OwnerContactInfo != "" && item.OwnerContactInfo != "[]" {
			type contactInfo []struct {
				Name        string `json:"name"`
				PhoneNumber string `json:"phone_number"`
			}
			var contact contactInfo
			_ = json.Unmarshal([]byte(item.OwnerContactInfo), &contact)
			for i, v := range contact {
				if i != 0 {
					ownerContacts += "、"
				}

				if len(v.PhoneNumber) > 7 {
					v.PhoneNumber = utils.GetMobileEncrypt(v.PhoneNumber)
				}

				if v.Name != "" {
					ownerContacts += v.Name + " " + v.PhoneNumber
				} else {
					ownerContacts += v.PhoneNumber
				}
			}
		}
		rowData = append(rowData, []string{
			item.Title,          //招标标题，
			item.DeveloperName,  //招标公司，
			item.OrganizingCode, //社会统一信用代码，
			item.CompanyType,    //公司类型，
			item.Type,           //招标类型，
			publishDate,         //发布时间，
			endDate,             //截止时间，
			fmt.Sprintf("%.02f元", item.PurchaseAmount), //采购预算，
			item.BiddingServiceCategory,                //服务类型，
			ownerContacts,                              //招标负责人联系方式，
			strings.Join(supplierNameArr, ","),         //中标单位，
			item.Link,                                  //招标原文链接，
			strings.Join(addressArr, ","),              //项目所在地，
			strings.Join(label, ","),                   //商机特点
		})
	}

	return
}
